import json
import urllib.parse
from datetime import datetime

from django.core import serializers

from django.shortcuts import render, redirect
from django.http import JsonResponse, QueryDict
from django.template.backends import django
from django.views import View
from django.views.decorators.clickjacking import xframe_options_exempt

from authManager.models import UserInfo, Role, Permission, get_permission_tree
from authManager.service.init_permission import init_permission
from django.contrib.auth.hashers import make_password, check_password


# Create your views here.

class DateEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, datetime):
            return obj.strftime('%Y-%m-%d %H:%M:%S')
        elif isinstance(obj, date):
            return obj.strftime("%Y-%m-%d")
        else:
            return json.JSONEncoder.default(self, obj)


def login(request):
    if request.method == "GET":
        return render(request, "login.html")
    elif request.method == "POST":
        body = json.loads(request.body.decode('utf-8'))
        username = body['username']
        password = body['password']
        href_search = body['hrefSearch']
        if '?next=' in href_search:
            href_search = href_search.split('?next=')[1]
        else:
            href_search = '/'
        if not UserInfo.objects.filter(username=username).exists():
            return JsonResponse({
                'code': 1,
                'message': '用户不存在！'
            })

        user_obj = UserInfo.objects.filter(username=username).first()

        check_login = check_password(password, user_obj.password)
        if not check_login:
            return JsonResponse({
                'code': 1,
                'message': '账号密码错误，请检查！'
            })
        elif user_obj.is_enabled:
            init_permission(request, user_obj)
            # 更新最后登录时间
            now_time = datetime.now().replace(microsecond=0)
            user = UserInfo.objects.get(username=username)
            user.last_login = now_time
            user.save()
            return JsonResponse({
                'code': 0,
                'message': '登录成功',
                'href_search': href_search
            })
        else:
            return JsonResponse({
                'code': 2,
                'message': '账号未启用，请联系管理员'
            })


def logout(request):
    request.session.flush()
    return redirect('auth:login')


def index(request):
    return render(request, 'index.html')


def user_list(request):
    users = UserInfo.objects.all()
    return render(request, 'user_list.html', {'users': users})


def user_create(request):
    role = Role.objects.all()
    return render(request, 'user_create.html', {'role': role})


def user_edit(request):
    # ...
    user_id = request.GET['ID']
    user = UserInfo.objects.filter(id=user_id)
    roles = Role.objects.all()
    return render(request, 'user_edit.html', {'user': user, 'roles': roles})


class UserView(View):
    def get(self, request):
        # 获取用户
        users = UserInfo.objects.prefetch_related('roles')
        json_data = json.loads(serializers.serialize('json', users))
        data = []
        for r in range(0, users.count()):
            role = list(users[r].roles.values('id', 'name'))
            json_data[r]['fields']['id'] = json_data[r]['pk']
            del json_data[r]['fields']['password']
            json_data[r]['fields']['roles'] = role
            data.append(json_data[r]['fields'])
        code = 0
        msg = '获取数据成功！'
        count = len(data)
        if self.request.GET.get('page'):
            # 如果是分页请求，则分页处理
            page = int(self.request.GET.get('page', 1))
            limit = int(self.request.GET.get('limit'))
            start = (page - 1) * limit
            end = page * limit
            data = data[start:end]

        message = {
            "code": code,
            "msg": msg,
            "count": count,
            "data": data
        }
        return JsonResponse(message)

    def delete(self, request):
        # 删除用户
        _id = QueryDict(request.body)['id']
        UserInfo.objects.get(id=_id).delete()
        code = 0
        msg = '删除用户成功'
        return JsonResponse({'code': code, 'msg': msg})

    def put(self, request):
        # 更新用户
        body = QueryDict(request.body)
        id = body['ID']
        username = body['username']

        if UserInfo.objects.filter(id=id, username=username).exists():
            user = UserInfo.objects.get(id=id, username=username)
        else:
            code = 1
            msg = '用户不存在！'
            message = {
                'code': code,
                'msg': msg,
            }
            return JsonResponse(message)

        email = body['email']
        roles = [int(role.strip('role[]')) for role in body.keys() if role.startswith('role')]
        password = body['password']
        try:
            if body['is_enabled'] == 'on':
                is_enabled = 1
        except:
            is_enabled = 0

        if password:
            user.set_password(password)

        if user.email != email:
            user.email = email
            if UserInfo.objects.filter(email=email).exists():
                code = 1
                msg = '邮箱已经被使用，请更换！'
                return JsonResponse({'code': code, 'msg': msg})

        if user.is_enabled != is_enabled:
            user.is_enabled = is_enabled

        if set(user.roles.values_list('id', flat=True)) != set(roles):
            user.roles.set(Role.objects.filter(id__in=roles))

        user.save()

        code = 0
        msg = 'user edit api '
        message = {
            'code': code,
            'msg': msg,
        }
        return JsonResponse(message)

    def post(self, request):
        # 创建用户
        username = request.POST['username']
        password = request.POST['password']
        email = request.POST['email']

        if 'is_enabled' in request.POST and request.POST['is_enabled'] == 'on':
            is_enabled = 1
        else:
            is_enabled = 0

        role = request.POST['role']

        if UserInfo.objects.filter(username=username).exists():
            code = 1
            msg = '用户名已经存在！'
            return JsonResponse({'code': code, 'msg': msg})

        if UserInfo.objects.filter(email=email).exists():
            code = 1
            msg = '邮箱已经存在！'
            return JsonResponse({'code': code, 'msg': msg})
        # 创建用户，并获取user对象
        user = UserInfo.objects.create(username=username, password=make_password(password), email=email,
                                       is_enabled=is_enabled)
        # 创建对应role对象
        role = Role.objects.filter(id=role).first()
        # 通过user对象的roles属性用add方法自动添加关联表数据
        user.roles.add(role)
        code = 0
        msg = '用户创建成功！'
        return JsonResponse({'code': code, 'msg': msg})


def menu_list(request):
    code = 0
    message = '获取menu菜单成功！'
    menu = request.session.get('menu')
    return JsonResponse({'code': code, 'message': message, 'menu': menu})


def permission_list(request):
    # permission = Permission.objects.all(all)
    return render(request, 'permission_list.html')


def permission_create(request):
    permissions = Permission.objects.all()
    return render(request, 'permission_create.html', {'permissions': permissions})


def permission_delete(request, permission_id):
    if request.method == 'DELETE':
        Permission.objects.get(id=permission_id).delete()
        code = 0
        msg = '删除许可成功'
        return JsonResponse({'code': code, 'msg': msg})


def permission_edit(request):
    # ...
    permission_id = request.GET['ID']
    permissions = Permission.objects.filter(id=permission_id)
    menu = Permission.objects.filter(is_menu=1, parent_id__isnull=True)
    return render(request, 'permission_edit.html', {'permissions': permissions, 'menu': menu})


# def permission_edit_api(request):
#     if request.method == 'PUT':


class PermissionView(View):

    def get(self, request):
        data = request.GET.keys()
        if 'role' in data:
            # 获取role和permission 树关系
            json_data = get_permission_tree()
            code = 0
            msg = '获取数据成功！'
            message = {
                "code": code,
                "msg": msg,
                "count": len(json_data),
                "data": json_data
            }
        else:
            permission = Permission.objects.all()
            json_data = json.loads(serializers.serialize('json', permission))
            data = []
            for r in range(0, permission.count()):
                json_data[r]['fields']['id'] = json_data[r]['pk']
                data.append(json_data[r]['fields'])

            code = 0
            msg = '获取数据成功！'
            count = len(data)
            if self.request.GET.get('page'):
                # 如果是分页请求，则分页处理
                page = int(self.request.GET.get('page', 1))
                limit = int(self.request.GET.get('limit'))
                start = (page - 1) * limit
                end = page * limit
                data = data[start:end]
            message = {
                "code": code,
                "msg": msg,
                "count": count,
                "data": data
            }
        return JsonResponse(message)

    def delete(self, request):
        body = QueryDict(self.request.body)
        Permission.objects.get(id=body['id']).delete()
        code = 0
        msg = '删除许可成功'
        return JsonResponse({'code': code, 'msg': msg})

    def put(self, request):
        body = request.body.decode('utf-8')
        data = urllib.parse.parse_qs(body)
        id = int(data['ID'][0])
        if Permission.objects.filter(id=id).exists():
            permission = Permission.objects.get(id=id)
        else:
            code = 1
            msg = '许可不存在！'
            message = {
                'code': code,
                'msg': msg,
            }
            return JsonResponse(message)

        name = data['name'][0]
        url = data['url'][0]
        method = [method.strip('method[]') for method in data.keys() if method.startswith('method')]
        if permission.name != name:
            permission.name = name

        if permission.url_name != url:
            permission.url_name = name

        if permission.method != method:
            permission.method = method

        if 'is_menu' in data:
            is_menu = 1
            if permission.is_menu != is_menu:
                permission.is_menu = is_menu

        if 'parent' in data:
            parent_id = data['parent'][0]
            if permission.parent_id != parent_id:
                permission.parent_id = parent_id

        permission.save()

        code = 0
        msg = '修改完成'
        message = {
            'code': code,
            'msg': msg,
        }
        return JsonResponse(message)

    def post(self, request):
        name = request.POST['name']
        url = request.POST['url']
        method = [method.strip('method[]') for method in request.POST.keys() if method.startswith('method')]
        parent_id = request.POST['parent_id']
        if 'is_menu' in request.POST and request.POST['is_menu'] == 'on':
            is_menu = 1
        else:
            is_menu = 0

        if Permission.objects.filter(name=name).exists():
            code = 1
            msg = '许可名称已经存在！请检查！'
            return JsonResponse({'code': code, 'msg': msg})

        # 创建permission
        Permission.objects.create(
            name=name,
            url_name=url,
            method=method,
            parent_id=parent_id,
            is_menu=is_menu
        )

        code = 0
        msg = '许可创建成功！'
        return JsonResponse({'code': code, 'msg': msg})


def role_list(request):
    return render(request, 'role_list.html', )


def role_create(request):
    return render(request, 'role_create.html', )


@xframe_options_exempt
def role_edit(request):
    _id = request.GET['ID']
    role = Role.objects.prefetch_related('permissions').filter(id=_id)
    json_role = json.loads(serializers.serialize('json', role))[0]
    all_permission = get_permission_tree()
    list_permission = json_role['fields']['permissions']
    for num in range(0, len(all_permission)):
        # 先判断parent 是否已经被选中
        if all_permission[num]['id'] in list_permission and len(all_permission[num]['children']) == 0:
            all_permission[num]['checked'] = 'true'
        # children 是否被选中
        for p_id in all_permission[num]['children']:
            if p_id['id'] in list_permission:
                p_id['checked'] = 'true'
    permissions = json.dumps(all_permission)
    return render(request, 'role_edit.html', {'permissions': permissions, 'role': json_role})


class RoleView(View):

    def get(self, request):
        role = Role.objects.prefetch_related('permissions')
        json_data = json.loads(serializers.serialize('json', role))
        data = []
        for r in range(0, role.count()):
            role_data = role[r].permissions.values('id', 'name')
            json_data[r]['fields']['permissions'] = list(role_data)
            json_data[r]['fields']['id'] = json_data[r]['pk']
            data.append(json_data[r]['fields'])

        code = 0
        msg = '获取数据成功！'
        count = len(data)
        if self.request.GET.get('page'):
            # 如果是分页请求，则分页处理
            page = int(self.request.GET.get('page', 1))
            limit = int(self.request.GET.get('limit'))
            start = (page - 1) * limit
            end = page * limit
            data = data[start:end]
        message = {
            "code": code,
            "msg": msg,
            "count": count,
            "data": data
        }
        return JsonResponse(message)

    def post(self, request):
        name = request.POST['name']
        if Role.objects.filter(name=name).exists():
            code = 1

            msg = '角色名称已经存在！'
            message = {
                "code": code,
                "msg": msg,
            }
            return JsonResponse(message)
        # 创建role
        role = Role.objects.create(
            name=name,
        )
        for permission in request.POST.keys():
            if permission.startswith('layuiTreeCheck'):
                id = int(request.POST[permission])
                if id != 9999:
                    # 创建对应role对象
                    p = Permission.objects.filter(id=id).first()
                    # 通过role对象的permissions属性用add方法自动添加关联表数据
                    role.permissions.add(p)
        code = 0

        msg = '创建角色成功！'
        message = {
            "code": code,
            "msg": msg,
        }
        return JsonResponse(message)

    def delete(self, request):
        body = QueryDict(self.request.body)
        id = body['id']
        Role.objects.get(id=id).delete()

        code = 0
        msg = '删除角色成功'
        message = {
            "code": code,
            "msg": msg,
        }
        # print(message)
        return JsonResponse(message)

    def put(self, request):
        body = QueryDict(self.request.body)
        id = body['ID']
        name = body['name']
        role = Role.objects.get(id=id, name=name)
        _permission_list = []

        for permission in body.keys():
            if permission.startswith('layuiTreeCheck'):
                id = int(body[permission])
                if id != 9999:
                    _permission_list.append(id)

        permissions = sorted(_permission_list)
        role_permissions = list(role.permissions.values_list('id', flat=True))
        if len(permissions) != len(role_permissions):
            role.permissions.set(Permission.objects.filter(id__in=permissions))
            print(role.permissions)
            role.save()
            code = 0
            msg = '更新角色成功'
            message = {
                "code": code,
                "msg": msg,
            }
            return JsonResponse(message)
        else:
            code = 0
            msg = '未检测到角色改动'
            message = {
                "code": code,
                "msg": msg,
            }
            return JsonResponse(message)
